<?php

namespace app\company\controller;

use app\company\model\StoreSalesman;
use app\company\model\StoreUser;
use app\company\model\StoreUserAccount;
use app\company\model\StoreUserBank;
use app\company\validate\StoreValidate;
use app\service\traits\Crud;
use app\company\model\Store as StoreModel;
use app\company\model\Supplier;
use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\Response;

class Store extends Base
{
    private StoreModel $model;

    use Crud;

    public function initialize()
    {
        parent::initialize();
        $this->model         = new StoreModel();
        $this->validateClass = StoreValidate::class;
        $this->field         = 'id,name,address,status,is_on_credit,racking_time,sold_out_time';
        $this->withSearch    = 'id,name,is_deliver_line_id';
        $this->append        = 'is_on_credit_text';
        $this->isGs          = true;
    }

    public function format($list): mixed
    {
        return $list->each(function ($item) {
            $item->store_user    = $item->storeUsers()->field('real_name,mobile')->find();
            $item->supplier_name = '';
        });
    }

    public function search(): Response
    {
        $param = request()->param();
        $sql   = $this->model;
        if ($this->isGs) $sql = $sql->Gs();
        $sql   = $sql->withSearch($this->withSearch, $param);
        $count = $sql->count();
        if (request()->param('page', 0)) {
            $sql = $sql->page($param['page'], $param['limit']);
        }
        $field = 'id';
        if (request()->param('field')) $field .= ',' . request()->param('field');
        $list = $sql->field($field)->order($this->orderSort)->select()->each(function ($item) use ($param){
            //是否勾选
            if(isset($param['store_user_id']) && $param['store_user_id']){
                $item->is_check = (bool)StoreSalesman::where('store_user_id', $param['store_user_id'])
                                                     ->where('store_id', $item->id)
                                                     ->value('id');
            }
        });
        return $this->success('获取成功', compact('list', 'count'));
    }

    public function detailFormat($info): mixed
    {
        $info->store_user      = $info->storeUsers()->field('id,real_name,mobile')->find();
        $info->store_user_bank = $info->storeUsers()->find()->storeUserBanks()->field("bank_type,bank_no,user_name,bank_branch")->find();
        if (!$info->store_user_bank) {
            $arr['bank_type']      = 1;
            $arr['bank_no']        = '';
            $arr['user_name']      = '';
            $arr['bank_branch']    = '';
            $info->store_user_bank = $arr;
        }
        $info->money        = StoreUserAccount::where('store_user_id', $info->store_user->id)->value('money');//负责人余额
        $info->supplier_ids = $info->storeSuppliers()->column('supplier_id');
        return $info->visible(explode(',', "id,name,address,is_on_credit,long,lat,credit_days,store_user,store_user_bank,money,supplier_ids"));
    }


    /**
     * 下载模板
     * @return Response
     */
    public function downloadTemplate(): Response
    {
        $sheet = [];
        //标题 目前写在前端了
        //经销商列表
        $sheet['supplier_list'] = Supplier::status(1)->gs($this->company_id)->field('id ,name')->select();
        return $this->success('下载成功', compact('sheet'));
    }

    /**
     * 导入模板
     * @return Response
     */
    public function import(): Response
    {
        if (!$sheet = request()->param('sheet', '')) return $this->error('数据为空');
        $errorList        = []; // 存放字段错误信息
        $failedImports    = []; // 记录导入失败数据
        $failedImportsNum = 0; // 记录导入失败的数量
        // 开启数据库事务
        $this->model->startTrans();
        try {
            foreach ($sheet as $item) {
                $validate = new StoreValidate();
                if (!$validate->scene('import')->batch(true)->check($item)) {
                    $errorList[] = $validate->getError();
                    $failedImportsNum++;
                    $failedImports[] = $item;
                    continue;
                }

                if(StoreUser::where('mobile',$item['mobile'])->count() > 0){
                    $errorList[] = '手机号已存在';
                    $failedImportsNum++;
                    $failedImports[] = $item;
                    continue;
                }

                if ($store = StoreModel::where('name', $item['name'])->field('id,name')->find()) {
                    if (StoreUser::where('store_id',$store->id)->where('real_name', $item['real_name'])->where('mobile', $item['mobile'])->count() > 0) {
                        $errorList[] = '该门店已存在----';
                        $failedImportsNum++;
                        $failedImports[] = $item;
                        continue;
                    }
                }

                $item['company_id']   = $this->company_id;
                $item['racking_time'] = time();
                $store                = \app\mini\model\Store::create($item);

                // 添加用户
                $addUser                = request()->only(['real_name', 'mobile']);
                $addUser['store_id']    = $store->id;
                $addUser['company_id']  = $store->company_id;
                $addUser['real_name']   = $item['real_name'];
                $addUser['mobile']      = $item['mobile'];
                $addUser['is_salesman'] = 2;
                $user                   = StoreUser::create($addUser);

                //添加银行卡
                if ($item['user_name'] || $item['bank_no'] || $item['bank_type'] || $item['bank_branch']) {
                    $add['store_id']      = $store->id;
                    $add['store_user_id'] = $user->id;
                    $add['user_name']     = $item['user_name'];
                    $add['bank_no']       = $item['bank_no'];
                    $add['bank_type']     = $item['bank_type'];
                    $add['bank_branch']   = $item['bank_branch'];
                    StoreUserBank::create($add);
                }

                //添加supplier_ids绑定关系
//                if ($ids = $item['supplier_ids']) {
//                    $array = [];
//                    foreach (explode(',', $ids) as $id) {
//                        $add['supplier_id'] = $id;
//                        $add['store_id']    = $store->id;
//                        $add['company_id']  = $store->company_id;
//                        $array[]            = $add;
//                    }
//                    (new StoreSupplier())->saveAll($array);
//                }
            }
            // 提交事务
            $this->model->commit();
            if ($failedImportsNum > 0) {
                $errorMsg    = "出现" . $failedImportsNum . "条数据导入失败，请下载错误数据并修改重新导入";
                $errorDetail = compact('errorMsg', 'errorList', 'failedImports');
                return $this->error('部分导入失败', $errorDetail);
            } else {
                return $this->success('导入成功');
            }
        } catch (\Exception $e) {
            // 发生异常时回滚事务
            $this->model->rollback();
            return $this->error('服务器内部错误');
        }
    }

    public function importExcel(): Response
    {
        $file = request()->file('file'); // 获取上传的文件
        if (!$file) {
            return $this->error('文件上传失败');
        }
        $reader = IOFactory::createReaderForFile($file);
        $reader->setReadDataOnly(true);
        $spreadsheet = $reader->load($file);
        $sheet = $spreadsheet->getActiveSheet();
        $highestRow = $sheet->getHighestRow();
        $highestColumn = $sheet->getHighestColumn();
        $failedImports = [];
        for ($row = 2; $row <= $highestRow; $row++) {
            // 读取单元格数据
            $data = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, '',
                                            true, true, true);

            $failedImports[] = $data[$row];
        }
        $this->model->startTrans();
        try {
            $this->getFields($failedImports);
            $this->model->commit();
        }catch (Exception $e){
            return $this->error($e->getMessage());
        }
        return $this->success('导入成功');
    }

    private function getFields( $rowData): void
    {
        foreach ($rowData as $item){
            $fields['name']    = trim($item['A']);
            $fields['address'] = trim($item['D']);
            // 根据地址获取经纬度
            $location = $this->getLatLngByAddress($fields['address']);
            $fields['long'] = $location['long'];
            $fields['lat'] = $location['lat'];
            $fields['company_id'] = $this->company_id;

            $userFields['company_id'] = $this->company_id;
            $userFields['real_name'] = trim($item['B']);
            $userFields['mobile'] = trim(str_replace("86", "", trim($item['C'])));
            $userFields['is_salesman'] = 2;

            $row = StoreModel::where('name', $fields['name'])->field('id,name')->find();
            $storeUser = false;
            if($row){
                $storeUserRow =  StoreUser::where('store_id',$row->id)
                                       ->where('real_name',$userFields['real_name'])
                                       ->where('mobile',$userFields['mobile'])
                                       ->find();
                if($storeUserRow) {
                    $storeUser = true;
                    continue;
                }
            }
            if(!$storeUser){
                //随便使用钩子函数导致，服气
                $storeModel = new \app\mini\model\Store();
                $storeModel->save($fields);

                //添加负责人
                $userFields['store_id'] = $storeModel->id;
                (new \app\company\model\StoreUser)->save($userFields);
            }
        }
    }

    /**
     * 获取地址的经纬度
     * @param string $address 详细地址
     * @return array|false 返回包含经度和纬度的数组，或者在失败时返回false
     * @throws Exception
     */
    public function getLatLngByAddress(string $address): bool|array
    {
        // 这里可以使用第三方地图服务API，例如高德地图API
        $url = "https://restapi.amap.com/v3/geocode/geo";
        $params = [
            'address' => $address,
            // 这里填写你的API Key
            'key' => 'aba6432273a67ac6ae2024f3325a19d0',
        ];

        // 构建查询字符串
        $queryString = http_build_query($params);
        $completeUrl = $url . "?{$queryString}";

        // 初始化CURL会话
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $completeUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        // 禁用SSL验证 （不推荐在生产环境中使用）
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        // 执行CURL请求
        $output = curl_exec($ch);
        // 关闭CURL会话
        curl_close($ch);

        if ($output === false) {
            exception('CURL Error: ' . curl_error($ch));
        }

        $response = json_decode($output, true);

        if (isset($response['status']) && $response['status'] == '1') {
            $arrlen = count($response['geocodes']);
            $idx = $arrlen-1;
            $location = explode(',',$response['geocodes'][$idx]['location']);
            // 获取经纬度
            $lng = $location[0];
            $lat = $location[1];
            return ['long' => $lng, 'lat' => $lat];
        } else {
            exception('获取经纬度失败'.'='.$address);
        }
    }

}